package io.renren.modules.job.task;

import io.renren.common.enums.CommonProcessStatus;
import io.renren.modules.customer.entity.MessageRequestEntity;
import io.renren.modules.customer.service.MessageRequestService;
import io.renren.thirdparty.sms.SmsApiClient;
import io.renren.thirdparty.sms.config.SmsProperties;
import io.renren.thirdparty.sms.domain.SendResultItem;
import io.renren.thirdparty.sms.domain.SmsSendingResponse;
import io.renren.thirdparty.sms.enums.RequestStatusType;
import io.renren.thirdparty.sms.enums.ResultType;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author sean
 * @since 2020-03-22
 *
 * 短信发送任务
 */
@Component("smsSendingTask")
public class SmsSendingTask implements ITask {

    private static final Logger LOGGER = LoggerFactory.getLogger(SmsSendingTask.class);

    @Autowired
    private SmsApiClient smsApiClient;

    @Autowired
    private SmsProperties smsProperties;

    @Autowired
    private MessageRequestService messageRequestService;

    @Override
    public void run(String params) {
        //找到处于pending状态的短信请求分批次进行发送
        List<MessageRequestEntity> pendingEntities = this.messageRequestService.getPendingMessageRequestEntities4Messaging(this.smsProperties.getBatchSize());
        LOGGER.debug("Got {} pending entities for messaging", pendingEntities == null ? 0 : pendingEntities.size());
        //发送短信
        if (pendingEntities != null && pendingEntities.size() > 0) {
            this.sendMessages(pendingEntities);
        }

        //找到处于fail状态的短信请求分批次发送
        List<MessageRequestEntity> failEntities = this.messageRequestService.getFailMessageRequestEntities4MessagingRetry(this.smsProperties.getBatchSize(), this.smsProperties.getMaxRetry());
        LOGGER.debug("Got {} fail entities for messaging", failEntities == null ? 0 : failEntities.size());
        //发送短信
        if (failEntities != null && failEntities.size() > 0) {
            this.sendMessages(failEntities);
        }
    }

    private void sendMessages(List<MessageRequestEntity> entities) {
        Map<String, String> requests = new HashMap<>();
        Map<String, MessageRequestEntity> entityMap = new HashMap<>();
        for (MessageRequestEntity entity : entities) {
            requests.put(entity.getMobilePhone(), entity.getMessageContent());
            entityMap.put(entity.getMobilePhone(), entity);
        }
        //发送短信
        try {
            SmsSendingResponse sendingResponse = this.smsApiClient.p2p(requests);
            if (sendingResponse != null) {
                LOGGER.debug("Got response from sms message service provider {}", sendingResponse.toString());
                LOGGER.info("Current balance is {}", sendingResponse.getBalance());
                if (sendingResponse.getStatus() == RequestStatusType.SUCCESS) {
                    this.updateByMobilePhone(entityMap, sendingResponse.getItems());
                    //清除
                    entityMap.clear();
                } else {
                    this.batchUpdateByRequestStatus(entities, sendingResponse.getStatus());
                }
            }
        } catch (Exception e) {
            LOGGER.error("Fail to send message due to exception found.");
            LOGGER.error(e.getMessage(), e);
        }
    }

    /**
     * 根据手机号码更新状态
     * @param entityMap
     * @param sendResultItems
     */
    private void updateByMobilePhone(Map<String, MessageRequestEntity> entityMap, List<SendResultItem> sendResultItems) {
        if(entityMap != null && entityMap.size() > 0 && sendResultItems != null && sendResultItems.size() > 0) {
            Date now = new Date();
            for(SendResultItem item : sendResultItems) {
                if (item != null) {
                    LOGGER.debug("Try to update the request entity according to phone number {} with mid {}", item.getMobile(), item.getMessageId());
                    if (entityMap.containsKey(item.getMobile()) && entityMap.get(item.getMobile()) != null) {
                        MessageRequestEntity entity = entityMap.get(item.getMobile());
                        entity.setRequestStatus(item.getResult() == ResultType.SUCCESS ? CommonProcessStatus.PROCESSING : CommonProcessStatus.FAIL);
                        entity.setRequestTime(now);
                        entity.setRequestCount(entity.getRequestCount() + 1);
                        if (StringUtils.isNotBlank(item.getMessageId())) {
                            entity.setMessageId(item.getMessageId().trim());
                        }
                        if(item.getResult() != ResultType.SUCCESS) {
                            entity.setResponseContent(item.getResult() == null ? "未知错误" : item.getResult().getDescription());
                        }
                        this.messageRequestService.updateById(entity);
                    }
                }
            }
        }
    }

    /**
     * 接口请求级别错误，统一更新状态
     *
     * @param entities
     * @param requestStatusType
     */
    private void batchUpdateByRequestStatus(List<MessageRequestEntity> entities, RequestStatusType requestStatusType) {
        if (entities != null) {
            Date now = new Date();
            entities.forEach(e -> {
                e.setRequestStatus(CommonProcessStatus.FAIL);
                e.setRequestTime(now);
                e.setRequestCount(e.getRequestCount() + 1);
                e.setResponseContent(requestStatusType == null ? "未知错误" : requestStatusType.getDescription());
            });
            this.messageRequestService.updateBatchById(entities);
        }
    }
}
